package user

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"io/ioutil"
	"net/url"
	"time"
	"zhuandan/redis_lib"
	//"github.com/bitly/go-simplejson"
	"github.com/gin-gonic/gin"
	//"github.com/xlstudio/wxbizdatacrypt"
	"net/http"
	"zhuandan/data_source"
	"zhuandan/models"
)

const (
	code2sessionURL   = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
	CREATE_QRCODE_URL = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s"
	Url               = "https://api.weixin.qq.com/wxa/getwxacode"
	appid             = "wxf64aa6106b875289"
	appsecret         = "dad526019f10a9d8acf67b225948563a"
	pturl             = "http://zdb.suishilian.com"
)

type KDRespBody struct {
	Code        string `json:"code" from:"code"`
	Laiyuan     int64  `json:"laiyuan" from:"laiyuan"`
	Pid         int64  `json:"pid" from:"pid"`
	AccessToken string `json:"access_token" from:"access_token"`
	Unionid     string `json:"unionid" from:"unionid"`
}

func UserLoginls(ctx *gin.Context) {
	token := Accesstoken()
	data1 := UnionIDhq(token, "oHQFC0d_6rBOGLMGeEZHhgaiFk88")

	data := Appaccountuser("oYA9O1ah2d3B35e0nc4-N7FPkCCw")
	fmt.Println(data1)
	//data := Appaccountuser(unionid)
	if data.User.AccountId == "" || data.User.AccountId == "39276" {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    300,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "账号不存在",
		})
		return
	}
}

func Userguanlian(ctx *gin.Context) {
	var user []models.User
	data_source.Db.Where("guanlian = 1").Find(&user)
	for _, u := range user {
		data := Appaccountuser(u.Unionid)
		if data.User.AccountId != "" {
			nickname := "微信用户"
			if data.User.Nickname != "" {
				nickname = data.User.Nickname
			}

			logo := pturl + "/upload/logo.png"
			if data.User.Headimgurl != "" {
				logo = data.User.Headimgurl
			}

			var phone string
			if data.User.Mobile != "" {
				phone = data.User.Mobile
			}

			adduser := models.User{
				Logo:     logo,
				Nickname: nickname,
				Phone:    phone,
				Guanlian: 2,
			}
			data_source.Db.Where("id = ?", u.ID).Updates(&adduser)
		}
	}
}

func UserLogin(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	code := json1.Code
	pid := json1.Pid
	//fmt.Println(code)
	//return
	//token := wxToken()
	open := Accesstoken2(code)
	//weixin1 := Accesstokengzh(open.Openid, open.AccessToken)
	//fmt.Println(weixin1)
	//return
	openid := open.Openid
	unionid := open.Unionid
	if openid == "" {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    300,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "账号不存在",
		})
		return
	}

	reqip := ctx.ClientIP()
	var user models.User
	data_source.Db.Where("routine_openid = ?", openid).First(&user)
	if user.ID > 0 {
		if user.RoutineOpenid == "" {
			ctx.JSON(http.StatusOK, gin.H{
				"code":    300,
				"error":   1,
				"success": 400,
				"data":    "on",
				"msg":     "账号不存在",
			})
			return
		}
	}

	//data := Appaccountuser(unionid)
	//var guanlian int64
	//guanlian = 2
	//nickname := "微信用户"
	//logo := pturl + "/upload/logo.png"
	//if data.User.AccountId == "" {
	//	guanlian = 1
	//
	//	weixin := Accesstokengzh(open.Openid, open.AccessToken)
	//	fmt.Println("weixin", weixin)
	//	nickname = weixin.Nickname
	//	logo = weixin.Headimgurl
	//}
	//var price float64
	//if data.User.Money != "" {
	//	price = utils.StrToFloat64(data.User.Money)
	//}

	//fmt.Println("price ------------------------", price)

	if user.ID > 0 {
		upuser := models.User{
			LoginTime: time.Now().Unix(),
			LoginIp:   reqip,
			LoginNum:  user.LoginNum + 1,
		}
		data_source.Db.Where("routine_openid = ?", openid).Updates(upuser)
	} else {
		weixin := Accesstokengzh(open.Openid, open.AccessToken)
		adduser := models.User{
			LoginTime:     time.Now().Unix(),
			LoginIp:       reqip,
			RoutineOpenid: openid,
			CreateTime:    time.Now().Unix(),
			LoginNum:      1,
			Logo:          weixin.Headimgurl,
			Nickname:      weixin.Nickname,
			Status:        1,
			Unionid:       unionid,
			Pid:           pid,
			Guanlian:      1,
			Identity:      2,
			Vip:           1,
			State:         1,
			Laiyuan:       1,
			Bangwowa:      2,
			Dakefu:        1,
			Ifbuy:         1,
		}
		data_source.Db.Create(&adduser)
	}
	var userinfo models.User
	data_source.Db.Where("routine_openid = ?", openid).First(&userinfo)

	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    userinfo,
		"msg":     "ok",
	})
	return
}

func Ceshi(ctx *gin.Context) {
	token := Accesstoken()
	unionid := UnionIDhq(token, "oYA9O1ah2d3B35e0nc4-N7FPkCCw")
	fmt.Println(unionid)
}

type ResponseOpenid struct {
	AccessToken string `json:"access_token"`
	Openid      string `json:"openid"`
	Unionid     string `json:"unionid"`
	Ticket      string `json:"ticket"`
}
type ResponseUnionID struct {
	Unionid string `json:"unionid"`
	Openid  string `json:"openid"`
}

func UnionIDhq(token, openid string) (data string) {
	fmt.Println("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + token + "&openid=" + openid + "&lang=zh_CN")
	resp, err := http.Get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + token + "&openid=" + openid + "&lang=zh_CN")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := ResponseUnionID{}
	fmt.Println(string(body), "-------------------")

	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r.Unionid
}
func userOpenid(code string) (data ResponseOpenid) {
	resp, err := http.Get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + appsecret + "&code=" + code + "&grant_type=authorization_code")
	//fmt.Println(code)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := ResponseOpenid{}
	fmt.Println(string(body))

	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

func Accesstoken2(code string) (data ResponseOpenid) {
	resp, err := http.Get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + appsecret + "&code=" + code + "&grant_type=authorization_code")
	//fmt.Println(code)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := ResponseOpenid{}
	//fmt.Println(string(body))

	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

func Accesstokengzh(openid, access_token string) (data Responseuser) {

	resp, err := http.Get("https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN")
	//fmt.Println(code)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := Responseuser{}
	fmt.Println(string(body))

	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

func Accesstoken() (data string) {

	ctx := context.Background()
	weixintoken, _ := redis_lib.Client.Get(ctx, "weixinAccesstokendzhuandanbao").Result()
	if weixintoken == "" || len(weixintoken) == 0 {
		resp, err := http.Get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appsecret)

		if err != nil {
			fmt.Println(err)
			return
		}
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		r := ResponseAccess{}
		//fmt.Println("token----------", string(body))
		tokenlog := models.Tokenlog{
			Addtime: time.Now().Unix(),
			Value:   string(body),
			Appid:   appid,
		}
		data_source.Db.Create(&tokenlog)
		//把请求到的结构反序列化到专门接受返回值的对象上面
		err = json.Unmarshal(body, &r)
		if err != nil {
			fmt.Println(err)
		}
		weixintoken = r.AccessToken
		redis_lib.Client.Set(ctx, "weixinAccesstokendzhuandanbao", weixintoken, 7000*time.Second)
	}
	return weixintoken

}

type ResponsewxToken struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int64  `json:"expires_in"`
}

func Accesstokengzhywd() (data string) {
	ctx := context.Background()
	weixintoken, _ := redis_lib.Client.Get(ctx, "weixinAccesstokendyewuduo").Result()
	if weixintoken == "" || len(weixintoken) == 0 {
		resp, err := http.Get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appidywd + "&secret=" + appsecretywd)

		if err != nil {
			fmt.Println(err)
			return
		}
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		r := ResponseAccess{}
		//fmt.Println("token----------", string(body))

		//把请求到的结构反序列化到专门接受返回值的对象上面
		err = json.Unmarshal(body, &r)
		if err != nil {
			fmt.Println(err)
		}
		weixintoken = r.AccessToken
		redis_lib.Client.Set(ctx, "weixinAccesstokendyewuduo", weixintoken, 7000*time.Second)
	}
	return weixintoken

}

//
//func wxToken() (data ResponsewxToken) {
//	ctx := context.Background()
//	weixintoken, _ := redis_lib.Client.Get(ctx, "weixinAccesstokendzhuandanbao").Result()
//	if weixintoken == "" || len(weixintoken) == 0 {
//		resp, err := http.Get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appsecret)
//		if err != nil {
//			fmt.Println(err)
//			return
//		}
//		defer resp.Body.Close()
//		body, err := ioutil.ReadAll(resp.Body)
//		r := ResponsewxToken{}
//		fmt.Println(string(body))
//
//		//把请求到的结构反序列化到专门接受返回值的对象上面
//		err = json.Unmarshal(body, &r)
//		if err != nil {
//			fmt.Println(err)
//		}
//		weixintoken = r.AccessToken
//		redis_lib.Client.Set(ctx, "weixinAccesstokendzhuandanbao", weixintoken, 7000*time.Second)
//		return r
//	}
//
//}

func Appaccountuser(unionid string) (data Responsewxuserdata) {
	value := url.Values{"token": {"yanwei123yanwei123yanwei123yanwe"}, "action": {"app_account_user"}, "unionid": {unionid}}
	//fmt.Println(value)
	resp, err := http.PostForm("https://data.yewudaotech.com/interface.php", value)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := Responsewxuserdata{}
	//fmt.Println(string(body))
	log := models.Log{
		Unionid: unionid,
		Addtime: time.Now().Unix(),
		Text:    string(body),
		Title:   "查询用户余额",
	}
	data_source.Db.Create(&log)
	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

type Responsewxuserdata struct {
	Status int64          `json:"status"`
	User   Responsewxuser `json:"user"`
}

type Responsewxuser struct {
	AccountId  string `json:"account_id"`
	Nickname   string `json:"nickname"`
	Headimgurl string `json:"headimgurl"`
	Mobile     string `json:"mobile"`
	Money      string `json:"money"`
}

func Appaccountmodify(remain, infoid string) (data Responsewxuserdata) {
	value := url.Values{"token": {"yanwei123yanwei123yanwei123yanwe"}, "action": {"app_info_num_modify"}, "total": {"4"}, "remain": {remain}, "info_id": {infoid}}
	//fmt.Println(value)
	resp, err := http.PostForm("https://data.yewudaotech.com/interface.php", value)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := Responsewxuserdata{}
	//fmt.Println(string(body))

	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

func sendWxAuthAPI(appid, appsecret, code string) (map[string]interface{}, error) {
	var wxMap map[string]interface{}
	url := fmt.Sprintf(code2sessionURL, appid, appsecret, code)
	resp, err := http.DefaultClient.Get(url)

	if err != nil {
		return wxMap, err
	}

	err = json.NewDecoder(resp.Body).Decode(&wxMap)
	if err != nil {
		return wxMap, err
	}
	defer resp.Body.Close()

	return wxMap, nil
}

// GenerateToken 生成Token值
func GenerateToken(mapClaims jwt.MapClaims, key string) (string, error) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, mapClaims)

	return token.SignedString([]byte(key))
}

// token: "eyJhbGciO...解析token"
func ParseToken(token string, secret string) (int, error) {
	claim, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
		return []byte(secret), nil
	})
	if err != nil {
		return 1, err
	}
	return int(claim.Claims.(jwt.MapClaims)["uid"].(float64)), nil
}
